import numpy as np
import pandas as pd
from unidecode import unidecode
import geopandas as gpd
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import HTML
import plotly.io as pio
import plotly.graph_objects as go
from plotly.subplots import make_subplots
datosEncuesta = pd.read_csv("./dataSalary.csv", index_col = 0)
datosEncuesta["What country do you work in?"] = datosEncuesta["What country do you work in?"].str.lower()
def map_country(value):
if pd.isnull(value): # Verificar si el valor es nulo
return value
lower_value = unidecode(value.lower().strip())
usa_keywords = [
"u.s.", "united states","united states", "united stat", "us", "america", "the united states", "the us",
"u. s", "u. s.", "u.a.", "u.s", "u.s.", "u.s>", "u.sa", "ua", "u.s.a.", "usa","united sttes",
"u.s.a", "uxz", "united y", "united statss", "uniteed states","uniyed states","uniter statez",
"usa (company is based in a us territory, i work remote)", "usa-- virgin islands",
"usa, but for foreign gov't", "uniited states", "unite states", "united states",
"united states of america", "unites states", "usa tomorrow", "unitef stated","unitied states",
"united states of american", "united stares", "united state", "united state of america","untied states",
"united stated", "united stateds", "united states is america", "unitedstates","unted states","united sates","uniyes states"
]
uk_keywords = ["united kingdom", "uk", "england","kingdom","u.k","englang"]
ca_keywords = ["canada","canda","canadw","csnada","canad"]
if any(keyword in lower_value for keyword in usa_keywords):
return "usa"
elif any(keyword in lower_value for keyword in uk_keywords):
return "uk"
elif any(keyword in lower_value for keyword in ca_keywords):
return "ca"
else:
return value.strip()
datosEncuesta["What country do you work in?"] = datosEncuesta["What country do you work in?"].apply(map_country)
datosEncuesta["What country do you work in?"] = datosEncuesta["What country do you work in?"].str.replace('$2,175.84/year is deducted for benefits', '')
datosEncuesta["What country do you work in?"] = datosEncuesta["What country do you work in?"].str.replace('i was brought in on this salary to help with the ehr and very quickly was promoted to current position but compensation was not altered.', '')
def convert_salary(row, columna):
currency = row['Please indicate the currency']
annual_salary = row[columna]
if isinstance(annual_salary, str) and ',' in annual_salary:
annual_salary = annual_salary.replace(',', '')
try:
annual_salary = pd.to_numeric(annual_salary)
except (ValueError, TypeError):
print(annual_salary)
return annual_salary
if currency == "USD":
return annual_salary * 3956.54
elif currency == "GBP":
return annual_salary * 5356.28
elif currency == "CAD":
return annual_salary * 3101.64
elif currency == "EUR":
return annual_salary * 4529.90
elif currency == "AUD/NZD":
return annual_salary * 2797.49
#elif currency == "Other" and row['Currency - other'].eq("USD").any():
#return annual_salary * 3956.54
elif currency == "CHF":
return annual_salary * 4520.35
elif currency == "ZAR":
return annual_salary * 208.69
elif currency == "SEK":
return annual_salary * 377.25
elif currency == "HKD":
return annual_salary * 505.60
elif currency == "JPY":
return annual_salary * 26.49
else:
return annual_salary
datosEncuesta['salario_anual'] = datosEncuesta.apply(lambda row: convert_salary(row, "What is your annual salary? (You'll indicate the currency in a later question. If you are part-time or hourly, please enter an annualized equivalent -- what you would earn if you worked the job 40 hours a week, 52 weeks a year.)"), axis=1)
datosEncuesta['compensaciones'] = datosEncuesta.apply(lambda row: convert_salary(row, "How much additional monetary compensation do you get, if any (for example, bonuses or overtime in an average year)? Please only include monetary compensation here, not the value of benefits."), axis=1)
datosEncuesta['total_salario'] = datosEncuesta['salario_anual'] + datosEncuesta['compensaciones']
# Especifica la ruta del archivo CSV donde deseas guardar tus datos
ruta_del_archivo_csv = './SalarySurvey.csv'
datosEncuesta.to_csv(ruta_del_archivo_csv, index=False, sep=',')
nuevos_nombres = {
'What industry do you work in?': 'Industria',
'Job title': 'Cargo',
'If your job title needs additional context, please clarify here:': 'Contexto del Cargo',
'What is your annual salary? (You\'ll indicate the currency in a later question. If you are part-time or hourly, please enter an annualized equivalent -- what you would earn if you worked the job 40 hours a week, 52 weeks a year.)': 'Salario Anual',
'How much additional monetary compensation do you get, if any (for example, bonuses or overtime in an average year)? Please only include monetary compensation here, not the value of benefits.': 'Compensación Adicional',
'Please indicate the currency': 'Moneda',
'If "Other," please indicate the currency here: ': 'Otra Moneda',
'If your income needs additional context, please provide it here:': 'Contexto de Ingresos',
'What country do you work in?': 'Pais',
'If you\'re in the U.S., what state do you work in?': 'Estado (EE. UU.)',
'What city do you work in?': 'Ciudad',
'How many years of professional work experience do you have overall?': 'Años de Experiencia Profesional Total',
'How many years of professional work experience do you have in your field?': 'Años de Experiencia Profesional en el Campo',
'What is your highest level of education completed?': 'Nivel de Educación',
'What is your gender?': 'Genero',
'What is your race? (Choose all that apply.)': 'Raza',
'ConvertedSalaryCop': 'Salario Convertido COP',
'salario_anual': 'Salario Anual COP',
'compensaciones': 'Compensaciones en COP',
'total_salario': 'Total Salario en COP'
}
# Renombrar las columnas
datosEncuesta = datosEncuesta.rename(columns=nuevos_nombres)
Analisis de los datos¶
print(f"La cantidad de encuestas respondidas fue de:{len(datosEncuesta[:])}")
La cantidad de encuestas respondidas fue de:28008
Descripcion de las variables:¶
| Variable | Descripción |
|---|---|
| 'What industry do you work in?' | Industria |
| 'Job title' | Cargo |
| 'If your job title needs additional context, please clarify here:' | Contexto del Cargo |
| 'What is your annual salary? (You'll indicate the currency in a later question. If you are part-time or hourly, please enter an annualized equivalent -- what you would earn if you worked the job 40 hours a week, 52 weeks a year.)' | Salario Anual |
| 'How much additional monetary compensation do you get, if any (for example, bonuses or overtime in an average year)? Please only include monetary compensation here, not the value of benefits.' | Compensación Adicional |
| 'Please indicate the currency' | Moneda |
| 'If "Other," please indicate the currency here: ' | Otra Moneda |
| 'If your income needs additional context, please provide it here:' | Contexto de Ingresos |
| 'What country do you work in?' | País |
| 'If you're in the U.S., what state do you work in?' | Estado (EE. UU.) |
| 'What city do you work in?' | Ciudad |
| 'How many years of professional work experience do you have overall?' | Años de Experiencia Profesional Total |
| 'How many years of professional work experience do you have in your field?' | Años de Experiencia Profesional en el Campo |
| 'What is your highest level of education completed?' | Nivel de Educación |
| 'What is your gender?' | Género |
| 'What is your race? (Choose all that apply.)' | Raza |
| 'ConvertedSalaryCop' | Salario Convertido COP |
| 'salario_anual' | Salario Anual COP |
| 'compensaciones' | Compensaciones en COP |
| 'total_salario' | mográfica de encuestados.
pd.set_option('display.float_format', '{:.3f}'.format)
columnas_mostrar = ['Salario Anual COP','Compensaciones en COP', 'Total Salario en COP']
datosEncuesta[columnas_mostrar].describe().apply(lambda x: x.map('{:,.3f}'.format))
| Salario Anual COP | Compensaciones en COP | Total Salario en COP | |
|---|---|---|---|
| count | 28,008.000 | 20,730.000 | 20,730.000 |
| mean | 361,085,574.349 | 46,797,025.534 | 405,729,305.595 |
| std | 2,425,489,069.881 | 173,987,562.851 | 372,106,924.416 |
| min | 0.000 | 0.000 | 0.000 |
| 25% | 211,005,954.000 | 0.000 | 227,641,900.000 |
| 50% | 295,157,884.000 | 7,913,080.000 | 321,376,800.000 |
| 75% | 419,393,240.000 | 39,565,400.000 | 474,784,800.000 |
| max | 403,567,080,000.000 | 5,934,810,000.000 | 19,798,700,247.760 |
# Convertir las columnas a tipo numérico (si es necesario)
datosEncuesta["Salario Anual COP"] = pd.to_numeric(datosEncuesta["Salario Anual COP"], errors='coerce')
datosEncuesta["Compensaciones en COP"] = pd.to_numeric(datosEncuesta["Compensaciones en COP"], errors='coerce')
# Calcular el rango intercuartílico (IQR) para cada columna
Q1_salario = datosEncuesta["Salario Anual COP"].quantile(0.25)
Q3_salario = datosEncuesta["Salario Anual COP"].quantile(0.75)
IQR_salario = Q3_salario - Q1_salario
Q1_compensaciones = datosEncuesta["Compensaciones en COP"].quantile(0.25)
Q3_compensaciones = datosEncuesta["Compensaciones en COP"].quantile(0.75)
IQR_compensaciones = Q3_compensaciones - Q1_compensaciones
# Definir los límites para considerar outliers
umbral_inferior_salario = Q1_salario - 1.5 * IQR_salario
umbral_superior_salario = Q3_salario + 1.5 * IQR_salario
umbral_inferior_compensaciones = Q1_compensaciones - 1.5 * IQR_compensaciones
umbral_superior_compensaciones = Q3_compensaciones + 1.5 * IQR_compensaciones
# Filtrar los datos para excluir outliers
datos_filtrados_salario = datosEncuesta[(datosEncuesta["Salario Anual COP"] >= umbral_inferior_salario) & (datosEncuesta["Salario Anual COP"] <= umbral_superior_salario)]
datos_filtrados_compensaciones = datosEncuesta[(datosEncuesta["Compensaciones en COP"] >= umbral_inferior_compensaciones) & (datosEncuesta["Compensaciones en COP"] <= umbral_superior_compensaciones)]
# Crear subgráficos
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.1, subplot_titles=('Salario Anual COP', 'Compensaciones en COP'))
# Agregar diagrama de caja para "Salario Anual COP"
fig.add_trace(go.Box(y=datos_filtrados_salario["Salario Anual COP"], name='Salario Anual COP'), row=1, col=1)
# Agregar diagrama de caja para "Compensaciones en COP"
fig.add_trace(go.Box(y=datos_filtrados_compensaciones["Compensaciones en COP"], name='Compensaciones en COP'), row=2, col=1)
# Personalizar el diseño
fig.update_layout(title='Diagramas de Caja - Salario y Compensaciones (Sin Outliers)', showlegend=False)
# Guardar el gráfico en un archivo HTML
pio.write_html(fig, file='boxplots_salario_compensaciones.html')
# Mostrar el gráfico
fig.show()
Como podemos ver en la tabla anterior, el promedio del salario de todos los encuestados es de 361,085,574 COP, y el promedio para las compensaciones es de 46,797,025 COP en donde da un resultado del promedio de los ingresos totales es de 405,729,305.59 COP. Tambien podemos notar que el salario , compensacion y el total maximos son: 403,567,080,000 - 5,934,810,000 - 19,798,700,247 algunos de estos valores se retiran para realizar el grafico ya que dificulta su visualizacion.
Distribucion de los encuestados¶
A continuacion se muestra la distribucion de los encuestados por todo el mundo
iframe_html = '<iframe width="1200" height="800" src="https://lookerstudio.google.com/embed/reporting/7084f187-5efa-41d5-966d-cf9c90bbc1aa/page/HLqpD" frameborder="0" style="border:0" allowfullscreen sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"></iframe>'
iframe_with_text = f'{iframe_html}<div style="text-align: center; margin-top: 10px; font-weight: bold;">Distribucion de los encuestados</div>'
# Mostrar el iframe en el notebook
HTML(iframe_with_text)
datosEncuesta["Salario Anual COP"] = pd.to_numeric(datosEncuesta["Salario Anual COP"], errors='coerce')
# Calcular el promedio y agrupar por 'Industria'
promedio_por_industria_salario = datosEncuesta.groupby(['Industria'])['Salario Anual COP'].mean().reset_index()
promedio_por_industria_compensaciones = datosEncuesta.groupby(['Industria'])['Compensaciones en COP'].mean().reset_index()
# Ordenar por salario anual de mayor a menor
promedio_por_industria_salario = promedio_por_industria_salario.sort_values(by='Salario Anual COP', ascending=False)
promedio_por_industria_compensaciones = promedio_por_industria_compensaciones.sort_values(by='Compensaciones en COP', ascending=False)
# Seleccionar los 10 mayores
top_10_industrias_salario = promedio_por_industria.head(14)
top_10_industrias_compensaciones = promedio_por_industria_compensaciones.head(14)
fig_salario = go.Figure(go.Bar(
x=top_10_industrias_salario["Industria"],
y=top_10_industrias_salario["Salario Anual COP"],
name='Salario Anual COP',
))
fig_salario.update_layout(
title='Top 10 Industrias - Salario Anual COP',
xaxis=dict(tickangle=45),
height=600, # Ajustar la altura de la figura principal
width=800,
)
# Crear la figura para Compensaciones en COP
fig_compensaciones = go.Figure(go.Bar(
x=top_10_industrias_compensaciones["Industria"],
y=top_10_industrias_compensaciones["Compensaciones en COP"],
name='Compensaciones en COP',
marker=dict(color='red')
))
fig_compensaciones.update_layout(
title='Top 10 Industrias - Compensaciones en COP',
xaxis=dict(tickangle=45),
height=600, # Ajustar la altura de la figura principal
width=800,
)
# Mostrar las figuras en celdas distintas
fig_salario.show()
fig_compensaciones.show()
Como se muestra en la grafica anterior la industria que tiene un mayor promedio en el salario es Ipr seguida de telecommunicaciones y petroleo. por otra parte las industrias que tienen mejor compensacion son finanzas seguido de las comidas y bebidas.
conteo_genero = datosEncuesta["Genero"].value_counts()
datosEncuesta["Genero"] = datosEncuesta["Genero"].str.replace('Other or prefer not to answer', 'Prefer not to answer')
# Crear la figura utilizando Plotly
fig = go.Figure(data=[
# Gráfico de pastel
go.Pie(labels=conteo_genero.index, values=conteo_genero.values)
])
# Personalizar el diseño y título
fig.update_layout(
title='Distribución de Género en la Encuesta'
)
# Mostrar la figura
fig.show()
En el grafico anterior podemos notar que la mayoria de las personas encuestadas son mujeres llevandose el 76.7%